/*
* BinaryMatrixRank.h
* Last edited: 21.07.2014
* Author: David Noack
*/
#pragma once
#include "NistTest.h"
#include <boost\math\special_functions\gamma.hpp>

/**
\class BinaryMatrixRank
\brief Implementation of the Nist BinaryMatrixRank-test
*/
class BinaryMatrixRank : public NistTest
{
	public:
		/** Construktor
		\param bitArray Represents the random bits which have to be tesed.
		\param bitArraySize The size of bitArry in bits.*/
		BinaryMatrixRank(bool* bitArray, int bitArraySize);

		/**Destructor*/
		~BinaryMatrixRank();

		/**Does nothing*/
		void start(){};

		/**Executes the BinaryMatrix-test at the bitArray, given by the constructor.
		\param size The number of bits you want to test within the bitArray.*/
		double execute(int size);


	private:

		/**Determines the Rank of the current binary Matrix, saved in matrix nad increases
		one of the three counters countFullRank, countFullRank_minus1 or countOtherRanks.*/
		void determineRank();
		/**Initialzies the current matrix
		\param number of the matrix*/
		void fillMatrix(int matrixCount);
		/**Performs the Gauss Algorithm forward*/
		void performForwardOperations();
		/**Performs the Gauss Algorithm backwards*/
		void performBackwardOperations();
		/**Swaps two rows in the current matrix*/
		void swap(short row1, short row2);
		/**Helps debugging*/
		void printMatrix();

		/** Xor Operation
		\param var1 First bit
		\param var2 Second bit
		\return Xor result of first and second bit*/
		bool xor(bool var1, bool var2)
		{
			if (var1 != var2)
				return true;
			else
				return false;
		}

		/**number of rows, called M in NIST doc */
		int matrixRows; 
		/**number of columns, called Q in NIST doc*/
		int matrixColumns; 
		/**Representing a binary Matrix*/
		bool** matrix;
		/**called N in NIST doc*/
		int numberOfmatrices;
		/**Chi-Square Distribution*/
		double chi_sqr;

		/**FM*/
		int countFullRank;
		/**FM-1*/
		int countFullRank_minus1;
		/**N-FM-1*/
		int countOtherRanks;

};

